Unix Domain Sockets (UDS) হলো Inter-Process Communication (IPC) এর একটি প্রোটোকল, যা একাধিক প্রক্রিয়ার (process) মধ্যে ডেটা আদান-প্রদানের জন্য ব্যবহৃত হয়। এটি একই সিস্টেমের (মেশিনের) মধ্যে প্রক্রিয়াগুলোর মধ্যে যোগাযোগ স্থাপন করতে সক্ষম। UDS নেটওয়ার্ক সিস্টেমের বাইরে থাকে, অর্থাৎ এটি কেবলমাত্র লোকালহোস্টের (localhost) বা একই সিস্টেমের প্রক্রিয়াগুলোর জন্য কাজ করে। এটি TCP/IP বা UDP প্রোটোকলের বিকল্প হিসেবে ব্যবহৃত হয়, যেখানে ডেটা দ্রুত আদান-প্রদানের জন্য নেটওয়ার্ক স্ট্যাক ব্যবহৃত হয় না।
socket()
, bind()
, listen()
, accept()
, এবং connect()
API ব্যবহার করে। তবে, UDS-এ IP Address এর পরিবর্তে লোকাল ফাইল সিস্টেমের একটি পাথ ব্যবহার করা হয়।Unix Domain Sockets সাধারণত নিম্নলিখিত কাজের জন্য ব্যবহৃত হয়:
নিচে একটি উদাহরণ দেওয়া হলো যেখানে একটি Unix Domain Socket ব্যবহার করে সার্ভার এবং ক্লায়েন্টের মধ্যে সংযোগ স্থাপন করা হয়:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKET_PATH "/tmp/uds_socket"
int main() {
int server_fd, client_fd;
struct sockaddr_un server_addr, client_addr;
socklen_t client_len;
char buffer[100];
// 1. Socket তৈরি করা
if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 2. ঠিকানা সেটআপ করা
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
// 3. Binding করা
unlink(SOCKET_PATH);
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 4. Listening করা
if (listen(server_fd, 5) < 0) {
perror("Listen failed");
close(server_fd);
exit(EXIT_FAILURE);
}
printf("Server is listening...\n");
client_len = sizeof(client_addr);
// 5. Accepting সংযোগ
if ((client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len)) < 0) {
perror("Accept failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 6. ডেটা গ্রহণ করা
int n = read(client_fd, buffer, sizeof(buffer));
buffer[n] = '\0';
printf("Client: %s\n", buffer);
// 7. ডেটা পাঠানো
write(client_fd, "Hello from server", 17);
// 8. Socket বন্ধ করা
close(client_fd);
close(server_fd);
unlink(SOCKET_PATH);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKET_PATH "/tmp/uds_socket"
int main() {
int client_fd;
struct sockaddr_un server_addr;
char buffer[100];
// 1. Socket তৈরি করা
if ((client_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 2. সার্ভার ঠিকানা সেটআপ করা
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
// 3. সার্ভারের সাথে সংযোগ স্থাপন করা
if (connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
close(client_fd);
exit(EXIT_FAILURE);
}
// 4. ডেটা পাঠানো
write(client_fd, "Hello from client", 17);
// 5. ডেটা গ্রহণ করা
int n = read(client_fd, buffer, sizeof(buffer));
buffer[n] = '\0';
printf("Server: %s\n", buffer);
// 6. Socket বন্ধ করা
close(client_fd);
return 0;
}
socket()
ফাংশন AF_UNIX এবং SOCK_STREAM দিয়ে Socket তৈরি করে।listen()
ফাংশন সার্ভারকে ইনকামিং সংযোগের জন্য অপেক্ষা করায়।accept()
ফাংশন ইনকামিং সংযোগ গ্রহণ করে।read()
এবং write()
ফাংশন ক্লায়েন্ট থেকে ডেটা গ্রহণ এবং ক্লায়েন্টে ডেটা পাঠানোর জন্য ব্যবহৃত হয়।socket()
ফাংশন AF_UNIX এবং SOCK_STREAM দিয়ে ক্লায়েন্টের Socket তৈরি করে।connect()
ফাংশন সার্ভারের সাথে সংযোগ স্থাপন করে।write()
এবং read()
ফাংশন ডেটা পাঠানো এবং গ্রহণের জন্য ব্যবহৃত হয়।Unix Domain Sockets (UDS) হলো একটি Inter-Process Communication (IPC) মেকানিজম, যা একই মেশিনের (সিস্টেমের) মধ্যে চলমান প্রক্রিয়াগুলোর মধ্যে দ্রুত এবং কার্যকরভাবে ডেটা আদান-প্রদান করতে ব্যবহৃত হয়। এটি TCP/IP স্যুট-এর বিকল্প হিসেবে ব্যবহৃত হয়, যেখানে প্রক্রিয়াগুলো নেটওয়ার্ক প্রোটোকল ব্যবহার না করে লোকালি যোগাযোগ করে। UDS প্রোটোকলটি সাধারণত AF_UNIX বা AF_LOCAL নামে পরিচিত এবং এটি লোকালহোস্টের মধ্যে প্রক্রিয়াগুলোর মধ্যে যোগাযোগের জন্য আদর্শ।
Unix Domain Sockets ব্যবহার করে লোকাল প্রক্রিয়াগুলোর মধ্যে IPC প্রয়োগ করা যায়। UDS বিভিন্ন অ্যাপ্লিকেশন এবং সার্ভিসে ব্যবহৃত হয়, যেমন ডাটাবেস সার্ভার, ডেমন, এবং সিস্টেম সার্ভিস, যেগুলো একই সিস্টেমের মধ্যে দ্রুত যোগাযোগের প্রয়োজন হয়।
নিচে একটি উদাহরণ দেওয়া হলো যেখানে Unix Domain Sockets ব্যবহার করে একটি সার্ভার এবং ক্লায়েন্ট তৈরি করা হয়েছে:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKET_PATH "/tmp/uds_socket"
int main() {
int server_fd, client_fd;
struct sockaddr_un server_addr, client_addr;
socklen_t client_len;
char buffer[100];
// 1. Socket তৈরি করা
if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 2. ঠিকানা সেটআপ করা
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
// 3. Binding করা
unlink(SOCKET_PATH);
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 4. Listening করা
if (listen(server_fd, 5) < 0) {
perror("Listen failed");
close(server_fd);
exit(EXIT_FAILURE);
}
printf("Server is listening...\n");
client_len = sizeof(client_addr);
// 5. Accepting সংযোগ
if ((client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len)) < 0) {
perror("Accept failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 6. ডেটা গ্রহণ করা
int n = read(client_fd, buffer, sizeof(buffer));
buffer[n] = '\0';
printf("Client: %s\n", buffer);
// 7. ডেটা পাঠানো
write(client_fd, "Hello from server", 17);
// 8. Socket বন্ধ করা
close(client_fd);
close(server_fd);
unlink(SOCKET_PATH);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKET_PATH "/tmp/uds_socket"
int main() {
int client_fd;
struct sockaddr_un server_addr;
char buffer[100];
// 1. Socket তৈরি করা
if ((client_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 2. সার্ভার ঠিকানা সেটআপ করা
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
// 3. সার্ভারের সাথে সংযোগ স্থাপন করা
if (connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
close(client_fd);
exit(EXIT_FAILURE);
}
// 4. ডেটা পাঠানো
write(client_fd, "Hello from client", 17);
// 5. ডেটা গ্রহণ করা
int n = read(client_fd, buffer, sizeof(buffer));
buffer[n] = '\0';
printf("Server: %s\n", buffer);
// 6. Socket বন্ধ করা
close(client_fd);
return 0;
}
socket()
ফাংশন AF_UNIX এবং SOCK_STREAM দিয়ে Socket তৈরি করে।listen()
ফাংশন সার্ভারকে ইনকামিং সংযোগের জন্য অপেক্ষা করায়।accept()
ফাংশন ইনকামিং সংযোগ গ্রহণ করে।read()
এবং write()
ফাংশন ক্লায়েন্ট থেকে ডেটা গ্রহণ এবং ক্লায়েন্টে ডেটা পাঠানোর জন্য ব্যবহৃত হয়।socket()
ফাংশন AF_UNIX এবং SOCK_STREAM দিয়ে ক্লায়েন্টের Socket তৈরি করে।connect()
ফাংশন সার্ভারের সাথে সংযোগ স্থাপন করে।write()
এবং read()
ফাংশন ডেটা পাঠানো এবং গ্রহণের জন্য ব্যবহৃত হয়।File-based Communication এমন একটি Inter-Process Communication (IPC) পদ্ধতি যেখানে ফাইল সিস্টেমের মাধ্যমে প্রক্রিয়াগুলোর মধ্যে ডেটা আদান-প্রদান করা হয়। এটি সাধারণত ইউনিক্স সিস্টেমে ব্যবহৃত হয়, যেখানে প্রক্রিয়াগুলো ফাইলের মাধ্যমে যোগাযোগ করে। File-based Communication-এর বেশ কিছু সুবিধা রয়েছে, যা নিচে আলোচনা করা হলো:
Persistence (স্থায়িত্ব):
Simple and Intuitive Implementation (সরল এবং সহজ বোধগম্য):
Compatibility (সামঞ্জস্য):
Data Logging এবং Auditing সুবিধা:
Large Data Handling (বড় ডেটা প্রক্রিয়াকরণ):
Asynchronous Communication (অসিঙ্ক্রোনাস যোগাযোগ):
Access Control এবং Security (অ্যাক্সেস কন্ট্রোল এবং নিরাপত্তা):
Interoperability (ইন্টারঅপারেবিলিটি):
Simplicity in Debugging (ডিবাগিং সহজ করে):
Storage এবং Archival সুবিধা:
Named এবং Unnamed Sockets-এর মধ্যে পার্থক্য এবং তাদের কাজের পদ্ধতি সম্পর্কে আলোচনা করা হলো:
Unnamed Sockets হলো এমন একটি socket যা কোনো নির্দিষ্ট নাম বা ঠিকানা সংযুক্ত ছাড়াই তৈরি হয়। এটি সাধারণত Inter-Process Communication (IPC) এর জন্য প্রক্রিয়াগুলোর মধ্যে যোগাযোগের জন্য ব্যবহৃত হয়।
Unnamed Sockets তৈরি করতে সাধারণত socketpair() ফাংশন ব্যবহার করা হয়। নিচে একটি উদাহরণ দেওয়া হলো:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
int main() {
int sockets[2];
char buffer[100];
// 1. Socket pair তৈরি করা
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
perror("socketpair");
exit(EXIT_FAILURE);
}
if (fork() == 0) { // Child process
close(sockets[0]);
char *message = "Hello from child";
write(sockets[1], message, strlen(message));
close(sockets[1]);
} else { // Parent process
close(sockets[1]);
read(sockets[0], buffer, sizeof(buffer));
printf("Parent received: %s\n", buffer);
close(sockets[0]);
}
return 0;
}
Named Sockets হলো এমন একটি socket যা একটি নির্দিষ্ট নাম বা পাথ (path) ব্যবহার করে তৈরি করা হয়। এটি Unix Domain Sockets (UDS) এর একটি উদাহরণ, যেখানে একটি সুনির্দিষ্ট পাথ বা নাম ব্যবহার করে IPC (Inter-Process Communication) সম্পন্ন করা হয়। Named Sockets সাধারণত ফাইল সিস্টেমের একটি অংশ হিসেবে তৈরি হয়।
/tmp
ডিরেক্টরিতে বা সিস্টেমের অন্য কোনো অংশে তৈরি করা হয়।নিচে একটি Named Socket-এর উদাহরণ দেওয়া হলো, যেখানে Unix Domain Socket ব্যবহার করে একটি সার্ভার এবং ক্লায়েন্ট তৈরি করা হয়েছে:
Server Program (C ভাষায়):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKET_PATH "/tmp/named_socket"
int main() {
int server_fd, client_fd;
struct sockaddr_un server_addr;
char buffer[100];
// 1. Socket তৈরি করা
if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 2. ঠিকানা সেটআপ করা
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
// 3. Binding করা
unlink(SOCKET_PATH);
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 4. Listening করা
if (listen(server_fd, 5) < 0) {
perror("Listen failed");
close(server_fd);
exit(EXIT_FAILURE);
}
printf("Server is listening...\n");
// 5. Accepting সংযোগ
if ((client_fd = accept(server_fd, NULL, NULL)) < 0) {
perror("Accept failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 6. ডেটা গ্রহণ করা
read(client_fd, buffer, sizeof(buffer));
printf("Client: %s\n", buffer);
// 7. Socket বন্ধ করা
close(client_fd);
close(server_fd);
unlink(SOCKET_PATH);
return 0;
}
Client Program (C ভাষায়):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKET_PATH "/tmp/named_socket"
int main() {
int client_fd;
struct sockaddr_un server_addr;
// 1. Socket তৈরি করা
if ((client_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 2. সার্ভার ঠিকানা সেটআপ করা
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
// 3. সার্ভারের সাথে সংযোগ স্থাপন করা
if (connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
close(client_fd);
exit(EXIT_FAILURE);
}
// 4. ডেটা পাঠানো
char *message = "Hello from client";
write(client_fd, message, strlen(message));
// 5. Socket বন্ধ করা
close(client_fd);
return 0;
}
বৈশিষ্ট্য | Unnamed Sockets | Named Sockets |
---|---|---|
ঠিকানা ব্যবহার | কোনো নাম বা ঠিকানা ব্যবহার করে না | একটি নির্দিষ্ট নাম বা পাথ ব্যবহার করে |
ব্যবহার | Parent এবং Child process এর মধ্যে সাময়িক IPC | দীর্ঘমেয়াদী বা স্থায়ী IPC এর জন্য |
ফাইল সিস্টেম | ফাইল সিস্টেমের ওপর নির্ভর করে না | ফাইল সিস্টেমের অংশ হিসেবে কাজ করে |
লোকাল বা রিমোট | শুধুমাত্র একই সিস্টেমে কাজ করে | শুধুমাত্র একই সিস্টেমে কাজ করে |
ব্যবহারিক উদাহরণ | socketpair() API | Unix Domain Sockets (AF_UNIX, SOCK_STREAM) |
নিচে Unix Domain Socket ব্যবহার করে একটি সার্ভার এবং ক্লায়েন্ট প্রোগ্রাম উদাহরণ দেওয়া হলো, যা প্রক্রিয়াগুলোর মধ্যে লোকালি (একই সিস্টেমে) যোগাযোগ করতে সহায়ক। এই উদাহরণে C ভাষা ব্যবহার করা হয়েছে, এবং এটি একটি Stream Socket (SOCK_STREAM) প্রোটোকল ব্যবহার করে TCP-এর মতো ধারাবাহিক (reliable) সংযোগ তৈরি করবে।
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKET_PATH "/tmp/uds_socket"
int main() {
int server_fd, client_fd;
struct sockaddr_un server_addr, client_addr;
socklen_t client_len;
char buffer[100];
// 1. Socket তৈরি করা
if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 2. ঠিকানা সেটআপ করা
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
// 3. Binding করা
unlink(SOCKET_PATH); // যদি আগে থেকে কোনো ফাইল থাকে, তা মুছে ফেলা
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 4. Listening করা
if (listen(server_fd, 5) < 0) {
perror("Listen failed");
close(server_fd);
exit(EXIT_FAILURE);
}
printf("Server is listening...\n");
client_len = sizeof(client_addr);
// 5. Accepting সংযোগ
if ((client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len)) < 0) {
perror("Accept failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 6. ডেটা গ্রহণ করা
int n = read(client_fd, buffer, sizeof(buffer));
buffer[n] = '\0';
printf("Client: %s\n", buffer);
// 7. ডেটা পাঠানো
write(client_fd, "Hello from server", 17);
// 8. Socket বন্ধ করা
close(client_fd);
close(server_fd);
unlink(SOCKET_PATH); // Socket ফাইল মুছে ফেলা
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKET_PATH "/tmp/uds_socket"
int main() {
int client_fd;
struct sockaddr_un server_addr;
char buffer[100];
// 1. Socket তৈরি করা
if ((client_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 2. সার্ভার ঠিকানা সেটআপ করা
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);
// 3. সার্ভারের সাথে সংযোগ স্থাপন করা
if (connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
close(client_fd);
exit(EXIT_FAILURE);
}
// 4. ডেটা পাঠানো
char *message = "Hello from client";
write(client_fd, message, strlen(message));
// 5. ডেটা গ্রহণ করা
int n = read(client_fd, buffer, sizeof(buffer));
buffer[n] = '\0';
printf("Server: %s\n", buffer);
// 6. Socket বন্ধ করা
close(client_fd);
return 0;
}
socket()
ফাংশন ব্যবহার করে AF_UNIX এবং SOCK_STREAM দিয়ে একটি Unix Domain Socket তৈরি করা হয়।bind()
ফাংশন ব্যবহার করে Socket-কে একটি নির্দিষ্ট পাথ (/tmp/uds_socket
) এ সংযুক্ত করা হয়।listen()
ফাংশন ইনকামিং সংযোগের জন্য সার্ভারকে অপেক্ষা করায়।accept()
ফাংশন ব্যবহার করে একটি ইনকামিং সংযোগ গ্রহণ করা হয়।read()
ফাংশন ক্লায়েন্ট থেকে ডেটা গ্রহণ করে।write()
ফাংশন ব্যবহার করে সার্ভার ক্লায়েন্টে ডেটা পাঠায়।close()
এবং unlink()
ফাংশন ব্যবহার করে Socket বন্ধ এবং মুছে ফেলা হয়।socket()
ফাংশন AF_UNIX এবং SOCK_STREAM দিয়ে ক্লায়েন্টের জন্য একটি Socket তৈরি করে।server_addr.sun_path
-এ সেট করা হয়।connect()
ফাংশন সার্ভারের সাথে সংযোগ স্থাপন করে।write()
ফাংশন ব্যবহার করে ক্লায়েন্ট একটি বার্তা পাঠায়।read()
ফাংশন ব্যবহার করে সার্ভার থেকে ডেটা গ্রহণ করে।close()
ফাংশন ব্যবহার করে Socket বন্ধ করা হয়।প্রথমে সার্ভার প্রোগ্রাম চালু করুন:
/tmp/uds_socket
পাথে একটি Unix Domain Socket তৈরি করে এবং ইনকামিং সংযোগের জন্য অপেক্ষা করবে।এরপর ক্লায়েন্ট প্রোগ্রাম চালু করুন:
ক্লায়েন্ট এবং সার্ভারের মধ্যে বার্তা আদান-প্রদান:
common.read_more